<?php
/**
 * customer后台自有商品品牌的管理
 *
 * Author: lyun
 * Date: 2018/4/16
 * Created by Panxsoft.
 */
namespace App\Http\Controllers\Admin\Customer\Product;

use App\Http\Controllers\ApiController;
use App\Http\Requests\Admin\Customer\Brand\ProductBrandStoreRequest;
use App\Http\Requests\Admin\Customer\Brand\ProductBrandUpdateRequest;
use App\Models\Admin\CustomerAdmin;
use App\Models\Panx\Brand;
use App\Models\Panx\Product;
use App\Services\Utils\Guard;
use App\Services\Utils\Transaction;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;

class ProductBrandController extends ApiController
{
    const ROUTES = [
        'index'   => 'api.admin.customer.brand.index',
        'store'   => 'api.admin.customer.brand.store',
        'update'  => 'api.admin.customer.brand.update',
        'destroy' => 'api.admin.customer.brand.destroy',
    ];

    /**
     * Display a listing of the resource.
     * @test
     *
     * @param Request $request
     * @return \Illuminate\Http\Response
     * @throws \Exception
     */
    public function index(Request $request)
    {
        $this->checkIsTrue(CustomerAdmin::isGuardSuperAdmin(), trans('admin.is_super_man'));

        /** @var LengthAwarePaginator $brands */
        $brands = (new Brand)
            ->with('customer')
            ->where('customer_id', Guard::customerAdmin()->customer_id)
            ->orderBy($request->sort_column ?: 'created_at', $request->sort_by ?: 'DESC')
            ->paginate($request->per_page ?: 15);

        return $this->response(compact('brands','no_customer'));
    }

    /**
     * Store a newly created resource in storage.
     * @test
     *
     * @param  ProductBrandStoreRequest  $request
     * @return \Illuminate\Http\Response
     * @throws \Exception
     */
    public function store(ProductBrandStoreRequest $request)
    {
        $this->checkIsTrue(CustomerAdmin::isGuardSuperAdmin(), trans('admin.is_super_man'));

        $brand = $this->assembleBrand($request);

        $stored = Brand::create($brand);

        return $this->response(compact('stored'));
    }

    /**
     * Update the specified resource in storage.
     * @test
     *
     * @param  ProductBrandUpdateRequest  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     * @throws \Exception
     */
    public function update(ProductBrandUpdateRequest $request, $id)
    {
        $this->checkIsTrue(CustomerAdmin::isGuardSuperAdmin(), trans('admin.is_super_man'));

        /** @var Brand $brand */
        $brand = Brand::find($id);
            $this->checkIsExistAndCanOperate($brand);

        $brand_data = $this->assembleBrand($request);

        $updated = $brand->update($brand_data);

        return $this->response(compact('updated'));
    }

    /**
     * @test
     *
     * @param  int $id
     * @return \Illuminate\Http\Response
     * @throws \Exception
     */
    public function destroy($id)
    {
        $this->checkIsTrue(CustomerAdmin::isGuardSuperAdmin(), trans('admin.is_super_man'));

        /** @var Brand $brand */
        $brand = Brand::find($id);
            $this->checkIsExistAndCanOperate($brand);

        $deleted = Transaction::handle(function () use ($brand){
            $this->resetRelatedProducts($brand);
            $this->resetRelatedBrandSeries($brand);
            return $brand->delete();
        });

        return $this->response(compact('deleted'));
    }

    /**
     * @param ProductBrandStoreRequest|ProductBrandUpdateRequest|Request $request
     * @return array
     */
    private function assembleBrand(Request $request)
    {
        $data = [
            'name'        => trim($request->name),
            'customer_id' => Guard::customerAdmin()->customer_id,
            'sort'        => $request->sort ?: 0,
            'url'         => $request->url, // 客户可以清空 url
        ];

        if ($request->logo) {
            $data['logo'] = $request->logo;
        }

        return $data;
    }

    /**
     * 重置关联商品的数据
     * @param Brand $brand
     */
    private function resetRelatedProducts(Brand $brand): void
    {
        $brand->products()->update([
            'brand_id'        => Product::NO_BRAND_ID,
            'brand_series_id' => Product::NO_BRAND_SERIES_ID,
            'is_sale'         => Product::IS_NO_SALE,
        ]);
    }

    /**
     * 重置关联系列的商品
     * @param Brand $brand
     */
    private function resetRelatedBrandSeries(Brand $brand): void
    {
        $brand->brandSeries()->update([
            'brand_id' => Product::NO_BRAND_ID,
        ]);
    }

    /**
     * @param $brand
     * @throws \Exception
     */
    private function checkIsExistAndCanOperate(?Brand $brand): void
    {
        $this->checkItemExist($brand, trans('admin.brand'));
        $this->checkCanOperate(
            $brand->customer_id === Guard::customerAdmin()->customer_id,
            trans('admin.is_can_operate_brand')
        );
    }
}
